package db.facades;

import db.facadelocals.PatientFacadeLocal;
import db.entities.Patient;
import details.AddressDetails;
import details.PatientDetails;
import exceptions.PatientNotFoundException;
import exceptions.UsernameAlreadyExistsException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author jeroen
 */
@Stateless
public class PatientFacade implements PatientFacadeLocal {
    @PersistenceContext
    private EntityManager em;

    public void registerPatient(String username, String password, String ssn) throws UsernameAlreadyExistsException {
        if(findByUsername(username) == null){
            Patient patient = new Patient(username, password, ssn);
            create(patient);
        } else {
            throw new UsernameAlreadyExistsException(username);
        }
    }

    public void registerPatient(String username, String password, String ssn, String name,
                        String surname, String bloodgroup, Calendar birthday, AddressDetails address) throws UsernameAlreadyExistsException{
        if(findByUsername(username) == null){
            Patient patient = new Patient(username, password, ssn, name, surname, bloodgroup, birthday);
            patient.setAddress(address.getA1(), address.getA2(), address.getCity(), address.getPostalCode(), address.getCountry(), address.getPhone(), address.getEmail());
            create(patient);
        } else {
            throw new UsernameAlreadyExistsException(username);
        }
    }

    public void setPassword(String username, String password) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setPassword(password);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public void setSsn(String username, String ssn) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setSsn(ssn);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public void setName(String username, String name) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setName(name);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public void setSurname(String username, String surname) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setSurname(surname);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }
    public void setBloodgroup(String username, String bloodgroup) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setBloodgroup(bloodgroup);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public void setBirthday(String username, Calendar birthday) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setBirthday(birthday);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public void setAddress(String username, String a1, String a2, String city, String postalCode, String country, String phone, String email) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setAddress(a1, a2, city, postalCode, country, phone, email);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public boolean isValidLogin(String username, String password) {
        Patient patient = findByUsername(username);
        if(patient != null){
            if(patient.getPassword().equals(password))
                return true;
            else
                return false;
        } else {
            return false;
        }
    }

    public boolean existPatient(String username){
        Patient patient = findByUsername(username);
        if(patient != null)
            return true;
        else
            return false;
    }

    public Patient findByUsername(String username) {
        try {
            Patient patient = (Patient) em.createNamedQuery("findPatientByUsername").setParameter("username", username).getSingleResult();
            return patient;
        } catch (Exception e) {
            return null;
        }
    }

    public PatientDetails getPatient(String username) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        AddressDetails address = new AddressDetails(patient.getAddress().getAddressLine1(),
                                 patient.getAddress().getAddressLine2(), patient.getAddress().getCity(),
                                 patient.getAddress().getPostalCode(), patient.getAddress().getCountry(),
                                 patient.getAddress().getPhone(), patient.getAddress().getEmail());
        PatientDetails u = new PatientDetails(patient.getId(), patient.getUsername(), patient.getPassword(),
                                          patient.getSsn(), patient.getName(), patient.getSurname(),
                                          patient.getBloodgroup(), patient.getBirthday(), address,
                                          patient.getLastConsult(), patient.getNextConsult());
        return u;
    }

    public PatientDetails getPatient(Long id) throws PatientNotFoundException {
        Patient patient = find(id);
        AddressDetails address = new AddressDetails(patient.getAddress().getAddressLine1(),
                                 patient.getAddress().getAddressLine2(), patient.getAddress().getCity(),
                                 patient.getAddress().getPostalCode(), patient.getAddress().getCountry(),
                                 patient.getAddress().getPhone(), patient.getAddress().getEmail());
        PatientDetails u = new PatientDetails(patient.getId(), patient.getUsername(), patient.getPassword(),
                                          patient.getSsn(), patient.getName(), patient.getSurname(),
                                          patient.getBloodgroup(), patient.getBirthday(), address,
                                          patient.getLastConsult(), patient.getNextConsult());
        return u;
    }

    public void setGPs(String username, ArrayList<String> GPs) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setGPs(GPs);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public List<String> getGPs(String username) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            return patient.getGPs();
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public void addGPToPatient(String usernamePatient, String usernameGP) throws PatientNotFoundException {
        Patient patient = findByUsername(usernamePatient);
        if(patient != null){
            patient.addGP(usernameGP);
            edit(patient);
        } else {
            throw new PatientNotFoundException(usernamePatient);
        }
    }

    public void removeGPFromPatient(String usernamePatient, String usernameGP) throws PatientNotFoundException {
        Patient patient = findByUsername(usernamePatient);
        if(patient != null){
            patient.removeGP(usernameGP);
            edit(patient);
        } else {
            throw new PatientNotFoundException(usernamePatient);
        }
    }

    public void setLastConsult(String username, Date lastConsult) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setLastConsult(lastConsult);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public void setNextConsult(String username, Date nextConsult) throws PatientNotFoundException {
        Patient patient = findByUsername(username);
        if(patient != null){
            patient.setNextConsult(nextConsult);
            edit(patient);
        } else {
            throw new PatientNotFoundException(username);
        }
    }

    public List<PatientDetails> getAllPatients(){
        List<Patient> list = findAll();
        List<PatientDetails> pds = new ArrayList<PatientDetails>();

        for(Patient p : list){
            AddressDetails address = new AddressDetails(p.getAddress().getAddressLine1(),
                                 p.getAddress().getAddressLine2(), p.getAddress().getCity(),
                                 p.getAddress().getPostalCode(), p.getAddress().getCountry(),
                                 p.getAddress().getPhone(), p.getAddress().getEmail());
            PatientDetails u = new PatientDetails(p.getId(), p.getUsername(), p.getPassword(),
                                  p.getSsn(), p.getName(), p.getSurname(),
                                  p.getBloodgroup(), p.getBirthday(), address,
                                  p.getLastConsult(), p.getNextConsult());
            pds.add(u);
        }

        return pds;
    }

    public void create(Patient patient) {
        em.persist(patient);
    }

    public void edit(Patient patient) {
        em.merge(patient);
    }

    public void remove(Patient patient) {
        em.remove(em.merge(patient));
    }

    public Patient find(Object id) {
        return em.find(Patient.class, id);
    }

    public List<Patient> findAll() {
        return em.createQuery("select object(o) from Patient as o").getResultList();
    }


}
